package com.xunchi.haichuan.common.filter;

import java.io.File;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

/**
 * 作者：kongxb<br>
 * 模块名称：公共模块<br>
 * 功能描述：检查用户是否登录过滤器<br>
 * 维护记录：2009.11.21, kongxb 创建该类
 */
public class CheckLoginFilter implements Filter {

	private static final Logger logger = Logger.getLogger(CheckLoginFilter.class);

	public static final String USER_SESSION_KEY = "currentUser";

	/**
	 * The filter configuration object we are associated with. If this value is null, this filter instance is not
	 * currently configured.
	 */
	protected FilterConfig filterConfig = null;

	/**
	 * The filter check list, eg, that must be checked.
	 */
	protected String[] checkList = null;

	/**
	 * The filter not check list, eg, that must not be checked.
	 */
	protected String[] notCheckList = null;

	/**
	 * Should check login be ignored?
	 */
	protected boolean check = true;

	/**
	 * Take this filter out of service.
	 */
	public void destroy() {
		this.filterConfig = null;
		this.notCheckList = null;
	}

	/**
	 * Check user login or not.
	 * 
	 * @param servletRequest
	 *            The servlet request we are processing
	 * @param servletResponse
	 *            The servlet response we are creating
	 * @param chain
	 *            The filter chain we are processing
	 * 
	 * @exception IOException
	 *                if an input/output error occurs
	 * @exception ServletException
	 *                if a servlet error occurs
	 */
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;

		if (!check) {
			chain.doFilter(request, response);
			return;
		}

		String requestURI = request.getRequestURI();
		logger.debug("Request URI: " + requestURI);

		String requestPath = filterConfig.getServletContext().getRealPath(
				requestURI.replaceFirst(request.getContextPath(), ""));
		if ((new File(requestPath)).isDirectory()) {
			chain.doFilter(request, response);
			return;
		}

		String requestURILowerCase = requestURI.toLowerCase();
		if (checkList != null) {
			for (int i = 0; i < checkList.length; i++) {
				if (checkList[i].length() > 0 && requestURILowerCase.indexOf(checkList[i].toLowerCase()) > -1) {
					checkLogin(request, response, chain);
					return;
				}
			}
		}
		if (notCheckList != null) {
			for (int i = 0; i < notCheckList.length; i++) {
				if (notCheckList[i].length() > 0 && requestURILowerCase.indexOf(notCheckList[i].toLowerCase()) > -1) {
					chain.doFilter(request, response);
					return;
				}
			}
		}

		checkLogin(request, response, chain);
	}

	/**
	 * Place this filter into service.
	 * 
	 * @param filterConfig
	 *            The filter configuration object
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		String values = filterConfig.getInitParameter("checkList");
		if (values != null) {
			this.checkList = values.split(",");
		}
		values = filterConfig.getInitParameter("notCheckList");
		if (values != null) {
			this.notCheckList = values.split(",");
		}
		String value = filterConfig.getInitParameter("check");
		if (value == null) {
			this.check = true;
		} else if (value.equalsIgnoreCase("true")) {
			this.check = true;
		} else if (value.equalsIgnoreCase("yes")) {
			this.check = true;
		} else {
			this.check = false;
		}
	}

	/**
	 * Check user login or not.
	 * 
	 * @param request
	 *            The servlet request we are processing
	 * @param response
	 *            The servlet response we are creating
	 * @param chain
	 *            The filter chain we are processing
	 * 
	 * @exception IOException
	 *                if an input/output error occurs
	 * @exception ServletException
	 *                if a servlet error occurs
	 */
	protected void checkLogin(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpSession session = request.getSession();
		if (session != null && session.getAttribute(USER_SESSION_KEY) != null) {
			chain.doFilter(request, response);
		} else {
			logger.debug("Session had been invalidated, auto logout.");
			String requestURI = request.getRequestURI();
			String locale = "";
			if (request.getLocale() != null) {
				locale = request.getLocale().toString();
				if (locale != null && !"".equals(locale)) {
					locale = "_" + locale;
				}
			}
			RequestDispatcher dispatcher = request
					.getRequestDispatcher("/jsp/expired" + locale + ".jsp"/* "/error.do" */);
			request.setAttribute("Referer", requestURI);
			dispatcher.forward(request, response);
		}
	}

}
